package com.rj.core.math;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 数值计算器
 *
 * @author ranlubo
 */
public class Calc {
    /**
     * 计算数
     */
    private BigDecimal swap = null;

    public void setSwap(BigDecimal swap) {
        this.swap = swap;
    }

    /**
     * 创建一个BigDecimal 需要检查swap
     *
     * @param number
     * @return
     */
    public BigDecimal create(Object number) {
        return create(number, true);
    }

    /***
     *
     * @param number 数值
     * @param check 是否检查 swap
     * @return
     */
    public BigDecimal create(Object number, boolean check) {
        if (check) {
            if (this.swap == null) {
                throw new RuntimeException("初始数为空");
            }
        }
        if (number instanceof BigDecimal) {
            return (BigDecimal) number;
        }
        if (number instanceof Calc) {
            return ((Calc) number).getResult();
        }
        return new BigDecimal(number.toString());
    }


    /**
     * 提供精确的加法运算。
     *
     * @return 两个参数的和
     */
    public Calc add(Object number) {
        BigDecimal num2 = create(number);
        setSwap(swap.add(num2));
        return this;
    }

    /**
     * 提供精确的减法运算。
     *
     * @param number 被减数
     * @return 两个参数的差
     */
    public Calc sub(Object number) {
        BigDecimal num2 = create(number);
        setSwap(swap.subtract(num2));
        return this;
    }

    /**
     * 提供精确的乘法运算。
     *
     * @param number 被乘数
     * @return 两个参数的积
     */
    public Calc mul(Object number) {
        BigDecimal num2 = create(number);
        setSwap(swap.multiply(num2));
        return this;
    }

    /**
     * @param number 被除数
     * @return 两个参数的商
     */
    public Calc div(Object number) {
        BigDecimal num2 = create(number);
        setSwap(swap.divide(num2, 8, RoundingMode.HALF_UP));
        return this;
    }

    /**
     * 获得结果
     *
     * @return
     */
    public BigDecimal getResult() {
        return this.swap;
    }

    /**
     * 获得计算结果
     *
     * @return
     */
    public String value() {
        return this.swap.toPlainString();
    }

    /**
     * 获得结果四舍五入。
     *
     * @param scale 小数点后保留几位
     * @return
     */
    public String value(int scale) {
        return this.swap.setScale(scale, RoundingMode.HALF_UP).toPlainString();
    }


    /**
     * 提供精确的小数位四舍五入处理。
     *
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public double valueToDouble(int scale) {
        return this.swap.setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 比较大小
     *
     * @param number1
     * @param number2
     * @return
     */
    public int compareTo(Object number1, Object number2) {
        return create(number1, false).compareTo(create(number2, false));
    }

    /**
     * 比较大小
     *
     * @param dest
     * @return
     */
    public int compareTo(Object dest) {
        return this.swap.compareTo(create(dest, false));
    }

    /**
     * 计算税
     *
     * @param sl  数量
     * @param slv 税率（整数）
     * @return
     */
    public Calc calcTax(Object sl, Double slv) {
        return this.mul(sl).mul(slv);
    }
}
